package com.startx.core.tools;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlReader;
import com.startx.core.system.constants.Constants;

/**
 * 讀取yml配置文件為propreties
 * @author minghu.zhang
 */
public class YmlReader {
	
	/**
	 * propreties值
	 */
	private Map<String,Object> properties = new HashMap<>();
	
	/**
	 * 配置流
	 */
	private InputStream stream;
	/**
	 * 鍵值對前綴
	 */
	private String      prefix;
	/**
	 * 正則
	 */
	private final static String VAR_REG = "\\$\\{(.*?)\\}";
	/**
	 * 替換
	 */
	private final static Pattern PATTERN  = Pattern.compile(VAR_REG);
	
	/**
	 * 構造Reader對象
	 * @param input
	 * @param prefix
	 */
	public YmlReader(String prefix) {
		super();
		this.prefix = prefix;
	}
	
	/**
	 * 構造Reader對象
	 * @param input
	 * @param prefix
	 */
	public YmlReader() {
		super();
	}
	
	public Map<String,Object> readByStream(InputStream stream) {
		this.stream = stream;
		return readYml();
	}
	
	public Map<String,Object> readByClassPath(String path) {
		this.stream = YmlReader.class.getResourceAsStream(path);
		return readYml();
	}

	@SuppressWarnings("unchecked")
	private Map<String,Object> readYml() {
		
		try {
			if(Objects.nonNull(stream)) {
				YamlReader reader = new YamlReader(new InputStreamReader(stream));
				ymlToProperties(((Map<String, ?>)reader.read()), prefix);
				proptiesVariableSet();
			}
		} catch (YamlException e) {
			e.printStackTrace();
		}
		
		return properties;
	}
	
	/**
	 * 變量設置
	 */
	private void proptiesVariableSet() {
		for (String key : properties.keySet()) {
			Object value = properties.get(key);
			if(value instanceof String) {
				properties.put(key, stringVariableMatcher(value.toString()));
			}
		}
	}
	
	/**
	 * 替換字符串
	 * @param value
	 */
	private String stringVariableMatcher(String value) {
		
		String citeValue = value.toString();
		Matcher matcher = PATTERN.matcher(citeValue);
		
		while(matcher.find()) {
			String variable = matcher.group(1);
			if(properties.containsKey(variable)) {
				String citeResult = properties.get(variable).toString();
				citeValue = citeValue.replace("${"+variable+"}", citeResult);
			}
		}
		
		return citeValue;
	}
	
	/**
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private void ymlToProperties(Map<String,?> values,String prefix) {
		for (String key : values.keySet()) {
			Object value = values.get(key);
			if(value instanceof Map) {
				ymlToProperties((Map<String,?>)value,(isNotEmpty(prefix)?prefix+".":"")+key);
			} else {
				properties.put(prefix+"."+key, value);
			}
		}
	}
	
	/**
	 * 是否為空
	 * @param value
	 * @return
	 */
	private boolean isNotEmpty(String value) {
		return Objects.nonNull(value) && !Constants.EMPTY_STRING.equals(value.trim());
	}
	
}
